package com.fast.alden.portal.service.impl;

import com.fast.alden.common.exception.BizException;
import com.fast.alden.common.exception.BizExceptionEnum;
import com.fast.alden.data.model.PortalUser;
import com.fast.alden.data.repo.PortalUserRepository;
import com.fast.alden.portal.service.PortalUserPortalService;
import jakarta.annotation.Resource;
import jakarta.transaction.Transactional;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.util.Base64;

@Service
public class PortalUserPortalServiceImpl implements PortalUserPortalService {
    @Resource
    private PortalUserRepository portalUserRepository;
    @Resource
    private PasswordEncoder passwordEncoder;

    @Override
    public PortalUser retrieveWithException(Long id) {
        return portalUserRepository.findById(id).orElseThrow(() -> new BizException(BizExceptionEnum.ENTITY_DATA_DOSE_NOT_EXIST, id));
    }

    @Override
    @Transactional
    public void updateLoginInfo(PortalUser entity) {
        if (entity == null) {
            throw new BizException(BizExceptionEnum.ENTITY_IS_NULL);
        }
        if (entity.getId() == null) {
            throw new BizException(BizExceptionEnum.ENTITY_ID_IS_NULL);
        }
        PortalUser user = this.retrieveWithException(entity.getId());
        user.setLastLoginIp(entity.getLastLoginIp());
        user.setLastLoginTime(entity.getLastLoginTime());

        portalUserRepository.save(user);
    }

    @Override
    public PortalUser findByAccount(String account) {
        PortalUser user = portalUserRepository.findByUsername(account).orElse(null);
        if (user != null) {
            return user;
        }
        user = portalUserRepository.findByPhone(account).orElse(null);
        if (user != null) {
            return user;
        }
        user = portalUserRepository.findByEmail(account).orElse(null);
        return user;
    }

    @Override
    public PortalUser create(PortalUser user) {
        user.setStatus(1);
        user.setPassword(passwordEncoder.encode(user.getPassword()));

        return portalUserRepository.save(user);
    }

    @Override
    public PortalUser update(PortalUser entity) {
        if (entity == null) {
            throw new BizException(BizExceptionEnum.ENTITY_IS_NULL);
        }
        if (entity.getId() == null) {
            throw new BizException(BizExceptionEnum.ENTITY_ID_IS_NULL);
        }
        PortalUser user = this.retrieveWithException(entity.getId());
        checkAccountBeforeUpdate(entity, user);
        // 编辑用户不支持修改ID、密码、头像、用户类型
        user.setUsername(entity.getUsername());
        user.setNickname(entity.getNickname());
        user.setRealName(entity.getRealName());
        user.setEmail(entity.getEmail());
        user.setPhone(entity.getPhone());
        user.setBirthday(entity.getBirthday());
        user.setIntroduce(entity.getIntroduce());
        user.setStatus(entity.getStatus());

        return portalUserRepository.save(user);
    }

    @Override
    public boolean existUsername(String username) {
        return portalUserRepository.findByUsername(username).isPresent();
    }

    @Override
    public boolean existPhone(String phone) {
        return portalUserRepository.findByPhone(phone).isPresent();
    }

    @Override
    public boolean existEmail(String email) {
        return portalUserRepository.findByEmail(email).isPresent();
    }

    @Override
    public void updatePassword(Long userId, String newPwd) {
        PortalUser user = retrieveWithException(userId);
        user.setPassword(passwordEncoder.encode(newPwd));
        portalUserRepository.save(user);
    }

    @Override
    public void updateAvatar(Long userId, MultipartFile file) throws IOException {
        PortalUser user = this.retrieveWithException(userId);

        InputStream inputStream = file.getInputStream();
        byte[] bytes = new byte[inputStream.available()];
        int size = inputStream.read(bytes);

        user.setAvatar("data:image/png;base64," + Base64.getEncoder().encodeToString(bytes));
        portalUserRepository.save(user);
    }

    @Override
    public void removeAvatar(Long userId) {
        PortalUser user = this.retrieveWithException(userId);

        user.setAvatar(null);
        portalUserRepository.save(user);
    }

    /**
     * 创建或修改前校验账户信息
     */
    private void checkAccountBeforeCreateOrUpdate(PortalUser target) {
        if (!StringUtils.hasText(target.getUsername())) {
            throw new BizException(BizExceptionEnum.USERNAME_CANT_BE_EMPTY);
        }
        if (!StringUtils.hasText(target.getPhone())) {
            throw new BizException(BizExceptionEnum.PHONE_CANT_BE_EMPTY);
        }
        if (!StringUtils.hasText(target.getEmail())) {
            throw new BizException(BizExceptionEnum.EMAIL_CANT_BE_EMPTY);
        }
    }

    /**
     * 修改前校验账户信息
     */
    private void checkAccountBeforeUpdate(PortalUser target, PortalUser source) {
        checkAccountBeforeCreateOrUpdate(target);
        if (!target.getUsername().equals(source.getUsername())) {
            if (existUsername(target.getUsername())) {
                throw new BizException(BizExceptionEnum.USERNAME_EXISTS);
            }
        }
        if (!target.getPhone().equals(source.getPhone())) {
            if (existPhone(target.getPhone())) {
                throw new BizException(BizExceptionEnum.PHONE_EXISTS);
            }
        }
        if (!target.getEmail().equals(source.getEmail())) {
            if (existEmail(target.getEmail())) {
                throw new BizException(BizExceptionEnum.EMAIL_EXISTS);
            }
        }
    }
}
